from fastapi import APIRouter, Request, Form, Depends, Query, Body, HTTPException
from fastapi.responses import RedirectResponse, JSONResponse
from fastapi.templating import Jinja2Templates
from sqlalchemy.orm import Session
from sqlalchemy import func, String, Date, cast, and_, or_
from sqlalchemy import extract
from database import get_db
from models import Users, UserType, Orders, OrderStatus, Kami, ApiCalls, ApiCallLogs, Config
from typing import Optional, List, Dict, Tuple
from passlib.context import CryptContext
import uuid, random, re
import hashlib
from datetime import datetime, timedelta, timezone, date

router = APIRouter(tags=["管理员模块"], prefix="/admin")
templates = Jinja2Templates(directory="templates")

ADMIN_SAFE = "safe2025"
# 分页配置
PAGE_SIZE = 20

pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")


def admin_required(request: Request):
    user = request.session.get("user")
    # 明确判断：user 不存在 或 不是管理员
    if user is None or (isinstance(user, dict) and user.get("is_admin") != 1):
        raise HTTPException(
            status_code=303,
            headers={"Location": "/admin/login"}
        )
    return user


@router.get("/login")
def login_page(request: Request):
    """返回登录页面"""
    return templates.TemplateResponse("admin/admin_login.html", {"request": request})


@router.post("/login")
async def admin_login(request: Request, username: str = Form(...), password: str = Form(...),
                      safe_code: str = Form(...), db: Session = Depends(get_db)):
    if safe_code != ADMIN_SAFE:
        return JSONResponse({"code": 0, "msg": "安全码错误"})

    user = db.query(Users).filter_by(username=username).first()
    if not user:
        return JSONResponse({"code": 0, "msg": "用户不存在"})

    # if user.password != hash_password(password):
    #     return JSONResponse({"code": 0, "msg": "密码错误"})

    if not pwd_context.verify(password, user.password):
        return JSONResponse({"code": 0, "msg": "密码错误"})

    if user.user_type.value != "admin":
        return JSONResponse({"code": 0, "msg": "非管理员、禁止访问"})

    request.session["user"] = {
        "user_id": user.user_id,
        "username": user.username,
        "is_admin": 1
    }

    return JSONResponse({"code": 1, "msg": "登录成功"})


@router.get("/logout")
def logout(request: Request):
    """退出登录"""
    request.session.clear()
    return RedirectResponse(url="/", status_code=303)


def get_dashboard_data(db: Session):
    now = datetime.now(timezone.utc)
    today = date.today()
    yesterday = today - timedelta(days=1)

    # -------------------------
    # 总用户数及上月对比
    # -------------------------
    total_users = db.query(func.count(Users.user_id)).scalar()

    # 上个月总用户数
    first_day_of_this_month = date(today.year, today.month, 1)
    last_month_last_day = first_day_of_this_month - timedelta(days=1)
    first_day_of_last_month = date(last_month_last_day.year, last_month_last_day.month, 1)

    users_last_month = db.query(func.count(Users.user_id)).filter(
        Users.created_at < first_day_of_this_month
    ).scalar()

    total_users_growth = round(
        ((total_users - users_last_month) / users_last_month) * 100, 2
    ) if users_last_month > 0 else 0

    # -------------------------
    # 今日新增用户及昨日对比
    # -------------------------
    today_new_users = db.query(func.count(Users.user_id)).filter(
        func.date(Users.created_at) == today
    ).scalar()

    yesterday_new_users = db.query(func.count(Users.user_id)).filter(
        func.date(Users.created_at) == yesterday
    ).scalar()

    today_user_growth = round(
        ((today_new_users - yesterday_new_users) / yesterday_new_users) * 100, 2
    ) if yesterday_new_users > 0 else 0

    # -------------------------
    # 本月订单数及上月对比
    # -------------------------
    first_day_of_month = date(today.year, today.month, 1)
    this_month_orders = db.query(func.count(Orders.order_id)).filter(
        Orders.created_at >= first_day_of_month
    ).scalar()

    # 上月订单
    last_month_orders = db.query(func.count(Orders.order_id)).filter(
        and_(
            Orders.created_at >= first_day_of_last_month,
            Orders.created_at <= last_month_last_day
        )
    ).scalar()

    month_order_growth = round(
        ((this_month_orders - last_month_orders) / last_month_orders) * 100, 2
    ) if last_month_orders > 0 else 0

    # -------------------------
    # 今日 API 调用次数及昨日对比
    # -------------------------
    today_api_calls = db.query(func.sum(ApiCalls.call_count)).filter(
        ApiCalls.call_date == today
    ).scalar() or 0

    yesterday_api_calls = db.query(func.sum(ApiCalls.call_count)).filter(
        ApiCalls.call_date == yesterday
    ).scalar() or 0

    api_calls_growth = round(
        ((today_api_calls - yesterday_api_calls) / yesterday_api_calls) * 100, 2
    ) if yesterday_api_calls > 0 else 0

    # -------------------------
    # 会员用户数量 及上周对比
    # -------------------------
    # 会员类型：month/season/year/admin（根据业务确认是否包含admin）
    vip_types = [UserType.month, UserType.season, UserType.year]
    # 若admin也算会员，可改为：vip_types = list(UserType) - [UserType.free]

    vip_count = db.query(func.count(Users.user_id)).filter(Users.user_type.in_(vip_types)).scalar() or 0

    # -------------------------
    # 活跃用户数量 及上周对比
    # -------------------------
    threshold = datetime.now().date() - timedelta(days=7)  # 30天前的日期

    active_count = (db.query(func.count(func.distinct(Users.user_id)))
                    .join(ApiCalls, Users.user_id == ApiCalls.user_id)
                    .filter(ApiCalls.call_date >= threshold)
                    .filter(ApiCalls.call_count > 0).scalar() or 0)

    # 最近7天：today → today-6天（共7天，含今天）
    recent7_start = datetime.now().date() - timedelta(days=6)
    recent7_end = datetime.now().date()

    # 前7天（8-14天前）：today-13天 → today-7天（共7天）
    prev7_start = datetime.now().date() - timedelta(days=13)
    prev7_end = datetime.now().date() - timedelta(days=7)

    active_recent7_count = (db.query(func.count(func.distinct(Users.user_id)))
                            .join(ApiCalls, Users.user_id == ApiCalls.user_id)
                            .filter(ApiCalls.call_date.between(recent7_start, recent7_end))
                            .filter(ApiCalls.call_count > 0).scalar() or 0)

    active_prev7_count = (db.query(func.count(func.distinct(Users.user_id)))
                          .join(ApiCalls, Users.user_id == ApiCalls.user_id)
                          .filter(ApiCalls.call_date.between(prev7_start, prev7_end))
                          .filter(ApiCalls.call_count > 0).scalar() or 0)

    week_active_growth = round(
        ((active_recent7_count - active_prev7_count) / active_prev7_count) * 100, 2
    ) if active_prev7_count > 0 else 0

    vip_recent7_count = (db.query(func.count(Users.user_id))
                         .filter(Users.activated_at.between(recent7_start, recent7_end))
                         .filter(Users.user_type.in_(vip_types)).scalar() or 0)

    vip_prev7_count = (db.query(func.count(Users.user_id))
                       .filter(Users.activated_at.between(prev7_start, prev7_end))
                       .filter(Users.user_type.in_(vip_types)).scalar() or 0)

    week_vip_growth = round(
        ((vip_recent7_count - vip_prev7_count) / vip_prev7_count) * 100, 2
    ) if vip_prev7_count > 0 else 0

    # -------------------------
    # 返回统计数据
    # -------------------------
    stats = {
        "total_users": total_users,
        "total_users_growth": total_users_growth,
        "today_new_users": today_new_users,
        "today_user_growth": today_user_growth,
        "this_month_orders": this_month_orders,
        "month_order_growth": month_order_growth,
        "today_api_calls": today_api_calls,
        "api_calls_growth": api_calls_growth,
        "vip_count": vip_count,
        "active_count": active_count,
        "week_active_growth": week_active_growth,
        "week_vip_growth": week_vip_growth
    }

    # 最近订单
    recent_orders_query = (
        db.query(Orders)
        .order_by(Orders.created_at.desc())
        .limit(10)
        .all()
    )

    recent_orders = []
    for order in recent_orders_query:
        recent_orders.append({
            "order_id": order.order_id,
            "username": order.user.username if order.user else "未知用户",
            "vip_type": order.vip_type.value,
            "pay_type": order.pay_type,
            "amount": order.amount,
            "status_label": "已支付" if order.status == OrderStatus.paid else "待支付" if order.status == OrderStatus.pending else "支付失败",
            "status_class": "success" if order.status == OrderStatus.paid else "warning" if order.status == OrderStatus.pending else "danger",
            "created_at": order.created_at.strftime("%Y-%m-%d %H:%M:%S")
        })

    return {
        "stats": stats,
        "recent_orders": recent_orders
    }


# 1. 接口1：获取API调用趋势数据（按时间范围：本周/本月/全年）
@router.get("/api_trend")
def get_api_trend(time_range: str = Query(default="week", enum=["week", "month", "year"]),
                  db: Session = Depends(get_db), admin_user=Depends(admin_required)):
    today = date.today()
    if time_range == "week":
        start_date = today - timedelta(days=today.weekday())
    elif time_range == "month":
        start_date = date(today.year, today.month, 1)
    else:  # year
        start_date = date(today.year, 1, 1)

    # 查询按月份分组的总调用次数
    if time_range == "year":
        trend_data = db.query(
            extract('month', ApiCalls.call_date).label('month'),
            func.sum(ApiCalls.call_count).label('total_calls')
        ).filter(
            ApiCalls.call_date >= start_date,
            ApiCalls.call_date <= today
        ).group_by(
            extract('month', ApiCalls.call_date)
        ).order_by(
            extract('month', ApiCalls.call_date)
        ).all()
    else:
        trend_data = db.query(
            ApiCalls.call_date,
            func.sum(ApiCalls.call_count).label('total_calls')
        ).filter(
            ApiCalls.call_date >= start_date,
            ApiCalls.call_date <= today
        ).group_by(
            ApiCalls.call_date
        ).order_by(
            ApiCalls.call_date
        ).all()

    # 处理数据格式（填充缺失月份/日期）
    if time_range == "year":
        # 生成1-12月的完整月份列表
        full_months = list(range(1, 13))
        # 转换为{month: total_calls}字典
        trend_dict = {row.month: row.total_calls for row in trend_data}
        # 填充缺失月份为0
        date_list = [datetime(today.year, month, 1).strftime('%m月') for month in full_months]
        calls_list = [trend_dict.get(month, 0) for month in full_months]
    else:
        # 处理周/月数据（原有逻辑）
        current_date = start_date
        date_list = []
        calls_list = []
        while current_date <= today:
            date_label = current_date.strftime('%m-%d') if time_range == "week" else current_date.strftime('%m-%d')
            date_list.append(date_label)
            daily_calls = next((item.total_calls for item in trend_data if item.call_date == current_date), 0)
            calls_list.append(daily_calls)
            current_date += timedelta(days=1)

    return JSONResponse({
        "success": True,
        "data": {
            "labels": date_list,
            "values": calls_list
        }
    })


# 2. 接口2：获取用户类型分布数据
@router.get("/user_distribution")
def get_user_distribution(db: Session = Depends(get_db), admin_user=Depends(admin_required)):
    """查询所有用户按类型（free/month/season/year/admin）的分布数量"""
    # 查询Users表：按user_type分组，统计各类型用户数量
    distribution_data = db.query(
        Users.user_type,  # 用户类型（枚举）
        func.count(Users.user_id).label("user_count")  # 该类型用户数量
    ).group_by(
        Users.user_type
    ).all()

    # 处理数据格式：映射枚举值为中文标签，确保所有类型都存在（无数据补0）
    # 枚举值与中文标签的映射（与前端显示一致）
    user_type_map = {
        UserType.free: "Free",
        UserType.month: "Month",
        UserType.season: "Season",
        UserType.year: "Year",
        UserType.admin: "Admin"
    }
    # 初始化所有类型数量为0
    type_counts = {type_key: 0 for type_key in user_type_map.keys()}

    # 填充查询到的数量
    for item in distribution_data:
        type_counts[item.user_type] = item.user_count

    # 转换为前端Chart.js要求的格式
    labels = [user_type_map[type_key] for type_key in type_counts.keys()]  # 类型标签
    values = [type_counts[type_key] for type_key in type_counts.keys()]  # 数量列表

    return JSONResponse({
        "success": True,
        "data": {
            "labels": labels,
            "values": values
        }
    })


@router.get("/dashboard")
def dashboard(request: Request, db: Session = Depends(get_db), admin_user=Depends(admin_required)):
    data = get_dashboard_data(db)
    return templates.TemplateResponse(
        "admin/admin_index.html",
        {
            "request": request,
            "admin_user": admin_user,
            **data
        }
    )


@router.get("/users")
def users(request: Request, page: int = Query(default=1, ge=1), page_size: int = Query(default=20, ge=1, le=50),
          search: str = "", db: Session = Depends(get_db), admin_user=Depends(admin_required)):
    # 基础查询
    query = db.query(Users)

    # 搜索
    if search:
        search_pattern = f"%{search}%"
        query = query.filter(
            or_(
                Users.username.ilike(search_pattern),
                Users.user_id.cast(String).ilike(search_pattern)
            )
        )

    # 总用户数
    total_users = query.count()

    # 分页计算
    offset = (page - 1) * page_size
    total_pages = (total_users + page_size - 1) // page_size  # 总页数（向上取整）

    # 分页
    users = query.order_by(Users.created_at.desc()).offset(offset).limit(page_size).all()

    # 今日日期
    today = datetime.now().date()

    # 遍历每个用户，绑定今日通话记录
    for user in users:
        # 查询当前用户的今日通话记录（使用 user.id 作为 user_id）
        today_call = (
            db.query(ApiCalls)
            .filter(
                ApiCalls.user_id == user.user_id,  # 关键：使用当前用户的 ID
                ApiCalls.call_date == today  # 匹配今日日期
            )
            .first()  # 获取第一条记录（或用 one()/all() 根据需求）
        )

        # 数据行 绑定到用户对象（添加属性 today_call）
        user.today_call = today_call  # 若没有记录则为 None

    data = get_dashboard_data(db)

    # 渲染模板
    return templates.TemplateResponse("admin/admin_users.html", {
        "request": request,
        "admin_user": admin_user,
        "users": users,
        "total_users": total_users,
        "total_pages": total_pages,
        "page": page,
        "page_size": page_size,
        "search": search,
        **data
    })


def user_param(user):
    return {
        "user_id": user.user_id,
        "username": user.username,
        "user_type": user.user_type.value,
        "status": user.status,
        "vip_expire": user.vip_expire.strftime("%Y-%m-%d") if user.vip_expire else None,
        "activation_method": user.activation_method.value if user.activation_method else None,
        "created_at": user.created_at.strftime("%Y-%m-%d %H:%M:%S") if user.created_at else None,
    }


@router.post("/users/action")
def user_action(request: Request, action: str = Query(...), payload: dict = Body(...), db: Session = Depends(get_db),
                admin_user=Depends(admin_required)):
    if action == "add":
        # 添加用户
        vip_expire_str = payload.get("vip_expire")
        if vip_expire_str:
            try:
                # 假设前端传入格式是 'YYYY-MM-DD'
                vip_expire = datetime.strptime(vip_expire_str, "%Y-%m-%d")
            except ValueError:
                vip_expire = None
        else:
            vip_expire = None

        password_str = payload.get("password")
        # password = hash_password(password_str)
        password = pwd_context.hash(password_str)

        valid_methods = ["wechat", "alipay", "kami", "manual", "other"]

        activation_method = payload.get("activation_method")
        if activation_method not in valid_methods:
            activation_method = 'other'  # 或 'other'

        new_user = Users(
            username=payload.get("username"),
            password=password,
            user_type=payload.get("user_type"),
            status=payload.get("status", 1),
            vip_expire=vip_expire,
            activation_method=activation_method,
            created_at=datetime.now()
        )
        db.add(new_user)
        db.commit()
        db.refresh(new_user)
        return JSONResponse({"success": True, "msg": "用户创建成功", "user_id": new_user.user_id})

    elif action == "view":
        # 查看用户详情
        user_id = payload.get("user_id")
        print("user_id:::", user_id)
        user = db.query(Users).filter(Users.user_id == user_id).first()
        if not user:
            return JSONResponse({"success": False, "msg": "用户不存在"})

        return JSONResponse({
            "success": True,
            "user": user_param(user)
        })

    elif action == "edit":
        # 编辑用户
        user_id = payload.get("user_id")
        user = db.query(Users).filter(Users.user_id == user_id).first()
        if not user:
            return JSONResponse({"success": False, "msg": "用户不存在"})
        action = payload.get("action")

        if action == "get":
            # 先将数据返给 admin/users/action?action=edit
            return JSONResponse({
                "success": True,
                "user": user_param(user)
            })
        else:
            # 更新数据
            if "username" in payload:
                user.username = payload["username"]
            if "status" in payload:
                user.status = payload["status"]
            if "user_type" in payload:
                user.user_type = payload["user_type"]
            if "activation_method" in payload:
                user.activation_method = payload["activation_method"]
            if "vip_expire" in payload:
                vip_expire_str = payload.get("vip_expire")
                if vip_expire_str:
                    try:
                        # 假设前端传入格式是 'YYYY-MM-DD'
                        user.vip_expire = datetime.strptime(vip_expire_str, "%Y-%m-%d")
                    except ValueError:
                        user.vip_expire = None
                else:
                    user.vip_expire = None

                # 🔑 只有当密码存在时才更新
            if "password" in payload and payload["password"]:
                # user.password = hash_password(payload["password"])
                user.password = pwd_context.hash(payload["password"])

            db.commit()
            return JSONResponse({"success": True, "msg": "更新成功"})

    elif action == "disable":
        # 禁用/启用用户
        user_id = payload.get("user_id")
        user = db.query(Users).filter(Users.user_id == user_id).first()
        if not user:
            return JSONResponse({"success": False, "msg": "用户不存在"})

        # 切换状态
        user.status = 0 if user.status == 1 else 1
        db.commit()
        return JSONResponse({"success": True, "msg": "用户状态更新成功", "status": user.status})

    elif action == "changeAuth":
        # 禁用/启用激活用户授权
        user_id = payload.get("user_id")
        user = db.query(Users).filter(Users.user_id == user_id).first()
        if not user:
            return JSONResponse({"success": False, "msg": "用户不存在"})

        # 切换状态
        user.vip_status = 0 if user.vip_status == 1 else 1
        db.commit()
        return JSONResponse({"success": True, "msg": "用户状态更新成功", "status": user.vip_status})

    elif action == "editAuth":
        # 编辑用户
        user_id = payload.get("user_id")
        user = db.query(Users).filter(Users.user_id == user_id).first()
        if not user:
            return JSONResponse({"success": False, "msg": "用户不存在"})
        action = payload.get("action")
        print("action:::", action)
        if action == "get":
            auth_dicts = {
                "user_id": user.user_id,
                "username": user.username,
                "user_type": user.user_type.value,
                "vip_status": user.vip_status,
                "vip_expire": user.vip_expire.strftime("%Y-%m-%d") if user.vip_expire else None,
                "activation_method": user.activation_method.value if user.activation_method else None,
                "created_at": user.created_at.strftime("%Y-%m-%d %H:%M:%S") if user.created_at else None,
            }

            return JSONResponse({
                "success": True,
                "user": auth_dicts
            })
        else:
            if "username" in payload:
                user.username = payload["username"]
            if "status" in payload:
                user.vip_status = payload["vip_status"]
            if "user_type" in payload:
                user.user_type = payload["user_type"]
            if "activation_method" in payload:
                user.activation_method = payload["activation_method"]
            if "vip_expire" in payload:
                vip_expire_str = payload.get("vip_expire")
                if vip_expire_str:
                    try:
                        # 假设前端传入格式是 'YYYY-MM-DD'
                        user.vip_expire = datetime.strptime(vip_expire_str, "%Y-%m-%d")
                    except ValueError:
                        user.vip_expire = None
                else:
                    user.vip_expire = None

                # 🔑 只有当密码存在时才更新

            db.commit()
            return JSONResponse({"success": True, "msg": "更新成功"})

    else:
        return JSONResponse({"success": False, "msg": "未知操作"})


def get_monthly_stats(db):
    now = datetime.now()
    # 本月第一天
    this_month_start = datetime(now.year, now.month, 1)
    # 上月最后一天
    last_month_end = this_month_start - timedelta(days=1)
    # 上月第一天
    last_month_start = datetime(last_month_end.year, last_month_end.month, 1)

    # ---------- 本月 ----------
    this_month_orders = db.query(func.count(Orders.order_id)) \
                            .filter(Orders.created_at >= this_month_start) \
                            .scalar() or 0

    this_month_amount = db.query(func.sum(Orders.amount)) \
                            .filter(Orders.created_at >= this_month_start) \
                            .scalar() or 0

    this_month_paid = db.query(func.sum(Orders.amount)) \
                          .filter(and_(Orders.created_at >= this_month_start,
                                       Orders.status == OrderStatus.paid)) \
                          .scalar() or 0

    this_month_unpaid = db.query(func.sum(Orders.amount)) \
                            .filter(and_(Orders.created_at >= this_month_start,
                                         Orders.status == OrderStatus.pending)) \
                            .scalar() or 0

    # ---------- 上月 ----------
    last_month_orders = db.query(func.count(Orders.order_id)) \
                            .filter(and_(Orders.created_at >= last_month_start,
                                         Orders.created_at <= last_month_end)) \
                            .scalar() or 0

    last_month_amount = db.query(func.sum(Orders.amount)) \
                            .filter(and_(Orders.created_at >= last_month_start,
                                         Orders.created_at <= last_month_end)) \
                            .scalar() or 0

    last_month_paid = db.query(func.sum(Orders.amount)) \
                          .filter(and_(Orders.created_at >= last_month_start,
                                       Orders.created_at <= last_month_end,
                                       Orders.status == OrderStatus.paid)) \
                          .scalar() or 0

    last_month_unpaid = db.query(func.sum(Orders.amount)) \
                            .filter(and_(Orders.created_at >= last_month_start,
                                         Orders.created_at <= last_month_end,
                                         Orders.status == OrderStatus.pending)) \
                            .scalar() or 0

    # ---------- 环比增长 ----------
    order_growth_rate = (
        (this_month_orders - last_month_orders) / last_month_orders * 100
        if last_month_orders > 0 else 0
    )
    amount_growth_rate = (
        (this_month_amount - last_month_amount) / last_month_amount * 100
        if last_month_amount > 0 else 0
    )
    paid_growth_rate = (
        (this_month_paid - last_month_paid) / last_month_paid * 100
        if last_month_paid > 0 else 0
    )
    unpaid_growth_rate = (
        (this_month_unpaid - last_month_unpaid) / last_month_unpaid * 100
        if last_month_unpaid > 0 else 0
    )

    return {
        "this_month": {
            "orders": this_month_orders,
            "total_amount": this_month_amount,
            "paid_amount": this_month_paid,
            "unpaid_amount": this_month_unpaid,
        },
        "last_month": {
            "orders": last_month_orders,
            "total_amount": last_month_amount,
            "paid_amount": last_month_paid,
            "unpaid_amount": last_month_unpaid,
        },
        "growth_rate": {
            "orders": order_growth_rate,  # %
            "amount": amount_growth_rate,  # %
            "paid": paid_growth_rate,  # %
            "unpaid": unpaid_growth_rate  # %
        }
    }


@router.get("/orders")
def orders(request: Request, page: int = Query(default=1, ge=1), page_size: int = Query(default=15, ge=1, le=50),
           search: str = "", status: Optional[str] = None,
           vip_type: Optional[str] = None, pay_type: Optional[str] = None, start_date: Optional[str] = None,
           end_date: Optional[str] = None, db: Session = Depends(get_db), admin_user=Depends(admin_required)):
    # 基础查询：关联用户
    query = db.query(Orders).join(Users)

    # 搜索用户名或用户ID
    if search:
        query = query.filter(
            (Users.username.ilike(f"%{search}%")) |
            (Orders.order_id.ilike(f"%{search}%"))
        )

    # 筛选状态
    # 只有参数存在才添加过滤
    if status:
        try:
            query = query.filter(Orders.status == OrderStatus(status))
        except ValueError:
            pass  # 忽略非法的 status 值

    if vip_type:
        try:
            query = query.filter(Orders.vip_type == UserType(vip_type))
        except ValueError:
            pass

    if pay_type:
        try:
            query = query.filter(Orders.pay_type == pay_type)
        except ValueError:
            pass

    if start_date and end_date:
        query = query.filter(Orders.created_at.between(start_date, end_date))

    # 总数
    total_orders = query.count()

    # 分页计算
    offset = (page - 1) * page_size
    total_pages = (total_orders + page_size - 1) // page_size  # 总页数（向上取整）

    # 分页
    orders_list = query.order_by(Orders.created_at.desc()).offset(offset).limit(page_size).all()

    # 构建前端需要的数据
    result = []
    for o in orders_list:
        result.append({
            "order_id": o.order_id,
            "user_id": o.user_id,
            "username": o.user.username,
            "vip_type": o.vip_type.value if o.vip_type else "",
            "pay_type": o.pay_type,
            "amount": o.amount,
            "status": o.status.value if o.status else "",
            "created_at": o.created_at.strftime("%Y-%m-%d %H:%M") if o.created_at else "",
            "is_verified": o.is_verified if o.is_verified else 0,
            "remark": o.remark,
            "paid_at": o.paid_at.strftime("%Y-%m-%d %H:%M") if o.paid_at else "-"
        })

    # 统计数据
    total_amount = db.query(func.sum(Orders.amount)).scalar() or 0
    paid_amount = db.query(func.sum(Orders.amount)).filter(Orders.status == OrderStatus.paid).scalar() or 0
    unpaid_amount = db.query(func.sum(Orders.amount)).filter(Orders.status == OrderStatus.pending).scalar() or 0
    total_orders = db.query(func.count(Orders.order_id)).scalar() or 0

    monthly_stats = get_monthly_stats(db)

    return templates.TemplateResponse(
        "admin/admin_order.html",
        {
            "request": request,  # 必须加
            "admin_user": admin_user,
            "orders": result,
            "total_orders": total_orders,
            "total_pages": total_pages,
            "page": page,
            "page_size": page_size,
            "stats": {
                "total_orders": total_orders,
                "total_amount": total_amount,
                "paid_amount": paid_amount,
                "unpaid_amount": unpaid_amount
            },
            "monthly_stats": monthly_stats
        }
    )


@router.get("/order_trend")
def order_trend(period: str = Query("day", regex="^(day|week|month)$"), db: Session = Depends(get_db)):
    now = datetime.now()
    if period == "day":
        # 按小时统计
        start_time = now.replace(hour=0, minute=0, second=0, microsecond=0)
        labels = [f"{h}:00" for h in range(24)]
        values = [0] * 24
        rows = (
            db.query(
                func.strftime("%H", Orders.created_at).label("hour"),
                func.sum(Orders.amount).label("total")
            )
            .filter(Orders.created_at >= start_time)
            .group_by("hour")
            .all()
        )
        for row in rows:
            values[int(row.hour)] = float(row.total)

    elif period == "week":
        # 按星期几统计
        start_time = now - timedelta(days=now.weekday())  # 本周一
        labels = ["周一", "周二", "周三", "周四", "周五", "周六", "周日"]
        values = [0] * 7
        rows = (
            db.query(
                func.strftime("%w", Orders.created_at).label("weekday"),
                func.sum(Orders.amount).label("total")
            )
            .filter(Orders.created_at >= start_time)
            .group_by("weekday")
            .all()
        )
        for row in rows:
            idx = (int(row.weekday) - 1) % 7
            values[idx] = float(row.total)

    else:  # month
        # 按天统计
        start_time = now.replace(day=1, hour=0, minute=0, second=0, microsecond=0)
        days_in_month = (now.replace(month=now.month % 12 + 1, day=1) - timedelta(days=1)).day
        labels = [f"{d}日" for d in range(1, days_in_month + 1)]
        values = [0] * days_in_month
        rows = (
            db.query(
                func.strftime("%d", Orders.created_at).label("day"),
                func.sum(Orders.amount).label("total")
            )
            .filter(Orders.created_at >= start_time)
            .group_by("day")
            .all()
        )
        for row in rows:
            idx = int(row.day) - 1
            values[idx] = float(row.total)

    return {"labels": labels, "values": values}


@router.post("/order/action")
def order_action(request: Request, action: str = Query(...), payload: dict = Body(...), db: Session = Depends(get_db),
                 admin_user=Depends(admin_required)):
    if action == "check":
        print("check")
        order_id = payload.get("order_id")
        print(order_id)
        order = db.query(Orders).filter(Orders.order_id == order_id).first()

        if not order:
            return JSONResponse({"success": False, "msg": "订单不存在"})
        print(payload)
        action = payload.get("action")

        if action == "get":
            order_dicts = {
                "order_id": order_id,
                "pay_type": order.pay_type,
                "amount": order.amount,
                "paid_at": order.created_at.strftime("%Y-%m-%d %H:%M:%S") if order.created_at else None,
                "status": order.status.value,
                "is_verified": order.is_verified,
                "remark": order.remark
            }

            # 先将数据返给 admin/users/action?action=edit
            return JSONResponse({
                "success": True,
                "order": order_dicts
            })
        else:
            # 更新数据
            if "status" in payload:
                order.status = payload["status"]
            if "is_verified" in payload:
                order.is_verified = payload["is_verified"]
            if "remark" in payload:
                order.remark = payload["remark"]
            db.commit()
            return JSONResponse({"success": True, "msg": "更新成功"})

    elif action == "hand":
        order_id = payload.get("order_id")
        print(order_id)
        order = db.query(Orders).filter(Orders.order_id == order_id).first()

        try:
            if order:
                # 更新已有订单
                # order.status = OrderStatus("paid")
                print(order.status, type(order.status))
                if order.status.value != "paid":
                    order.status = OrderStatus("paid")
                    order.paid_at = datetime.now(timezone.utc)
                    db.commit()
                    return JSONResponse({"success": True, "msg": f"订单已更新成功"})
                else:
                    return JSONResponse({"success": False, "msg": f"已支付订单, 无需补单"})
            else:
                # 新增订单
                return JSONResponse({"success": False, "msg": "非法操作"})

        except Exception as e:
            print(e)
            return JSONResponse({"success": False, "msg": str(e)})


# 计算百分比（保留一位小数）
def calc_percent(part, total):
    return round((part / total * 100) if total > 0 else 0, 1)


@router.get("/kami")
# 1. 卡密管理页面（获取列表+统计数据）
def kami_manage(request: Request, page: int = Query(default=1, ge=1), page_size: int = Query(default=15, ge=1, le=50),
                search: Optional[str] = Query(default=None), db: Session = Depends(get_db),
                admin_user=Depends(admin_required)):
    # ------------ 1. 卡密统计数据 ------------
    # 总卡密数
    total_kami = db.query(func.count(Kami.id)).scalar() or 0
    # 各类型卡密数（月/季/年）
    month_count = db.query(func.count(Kami.id)).filter(Kami.vip_type == UserType.month).scalar() or 0
    season_count = db.query(func.count(Kami.id)).filter(Kami.vip_type == UserType.season).scalar() or 0
    year_count = db.query(func.count(Kami.id)).filter(Kami.vip_type == UserType.year).scalar() or 0
    # 已使用/未使用数量
    used_kami = db.query(func.count(Kami.id)).filter(Kami.is_used == 1).scalar() or 0
    unused_kami = total_kami - used_kami
    used_percent = calc_percent(used_kami, total_kami)
    unused_percent = calc_percent(unused_kami, total_kami)
    # 已使用月卡 # 未使用月卡
    used_kami_month = db.query(func.count(Kami.id)).filter(and_(
        Kami.is_used == 1, Kami.vip_type == UserType.month)).scalar() or 0
    unused_kami_month = month_count - used_kami_month
    used_percent_month = calc_percent(used_kami_month, month_count)
    unused_percent_month = calc_percent(unused_kami_month, month_count)
    # 已使用半年卡 # 未使用月卡
    used_kami_season = db.query(func.count(Kami.id)).filter(and_(
        Kami.is_used == 1, Kami.vip_type == UserType.season)).scalar() or 0
    unused_kami_season = season_count - used_kami_season
    used_percent_season = calc_percent(used_kami_season, season_count)
    unused_percent_season = calc_percent(unused_kami_season, season_count)
    # 已使用半年卡 # 未使用月卡
    used_kami_year = db.query(func.count(Kami.id)).filter(and_(
        Kami.is_used == 1, Kami.vip_type == UserType.year)).scalar() or 0
    unused_kami_year = year_count - used_kami_year
    used_percent_year = calc_percent(used_kami_year, year_count)
    unused_percent_year = calc_percent(unused_kami_year, year_count)

    # ------------ 2. 卡密列表（分页+搜索） ------------
    # 基础查询
    query = db.query(Kami).outerjoin(Users, Kami.user_id == Users.user_id)  # 关联用户表（获取激活用户名）

    # 搜索过滤（搜索卡密code或用户名）
    if search:
        query = query.filter(
            (Kami.code.ilike(f"%{search}%")) |  # 卡密包含关键词
            (Users.username.ilike(f"%{search}%"))  # 用户名包含关键词
        )

    # 分页计算
    offset = (page - 1) * page_size
    total_pages = (total_kami + page_size - 1) // page_size  # 总页数（向上取整）
    # 执行查询（按创建时间倒序）
    kamis = query.order_by(Kami.created_at.desc()).offset(offset).limit(page_size).all()

    # 渲染页面
    return templates.TemplateResponse("admin/admin_kami.html", {
        "request": request,
        "admin_user": admin_user,
        # 统计数据
        "total_kami": total_kami,
        "month_count": month_count,
        "season_count": season_count,
        "year_count": year_count,
        "used_kami": used_kami,
        "unused_kami": unused_kami,
        "used_percent": used_percent,
        "unused_percent": unused_percent,
        "used_kami_month": used_kami_month,
        "unused_kami_month": unused_kami_month,
        "used_percent_month": used_percent_month,
        "unused_percent_month": unused_percent_month,
        "used_kami_season": used_kami_season,
        "unused_kami_season": unused_kami_season,
        "used_percent_season": used_percent_season,
        "unused_percent_season": unused_percent_season,
        "used_kami_year": used_kami_year,
        "unused_kami_year": unused_kami_year,
        "used_percent_year": used_percent_year,
        "unused_percent_year": unused_percent_year,
        # 列表数据
        "kamis": kamis,
        "page": page,
        "page_size": page_size,
        "total_pages": total_pages,
        "search": search,
    })


# 2. 生成卡密接口
@router.post("/kami/generate")
def generate_kami(vip_type: str = Form(...), count: int = Form(..., ge=1, le=100),
                  remark: Optional[str] = Form(default=None), db: Session = Depends(get_db),
                  admin_user=Depends(admin_required)):
    # 1. 验证卡密类型
    try:
        vip_type_enum = UserType[vip_type]
    except KeyError:
        return JSONResponse({"success": False, "msg": "无效的卡密类型"}, status_code=400)

    # 2. 定义各类型有效期（天）
    vip_days_map = {
        UserType.month: 30,
        UserType.season: 90,
        UserType.year: 365
    }
    days = vip_days_map[vip_type_enum]

    # 3. 批量生成卡密（确保code唯一）
    kami_list = []
    for _ in range(count):
        # 生成唯一卡密（UUID+随机字符串，避免重复）
        code = f"KAMI-{uuid.uuid4().hex[:8].upper()}-{random.randint(1000, 9999)}"
        # 检查卡密是否已存在（防止极端重复）
        while db.query(Kami).filter(Kami.code == code).first():
            code = f"KAMI-{uuid.uuid4().hex[:8].upper()}-{random.randint(1000, 9999)}"

        # 创建卡密记录
        kami = Kami(
            code=code,
            vip_type=vip_type_enum,
            days=days,
            is_used=0,  # 初始未使用
            remark=remark,
            created_at=datetime.now(timezone.utc)
        )
        kami_list.append(kami)

    # 4. 批量插入数据库
    db.add_all(kami_list)
    db.commit()

    msg_str = f"成功生成{count}张-{vip_type_enum.value} 卡密"
    return JSONResponse({
        "success": True,
        "msg": msg_str
    })


# 3. 更新卡密状态（启用/禁用）
@router.post("/kami/action")
def user_action(request: Request, action: str = Query(...), payload: dict = Body(...), db: Session = Depends(get_db),
                admin_user=Depends(admin_required)):
    if action == "editKami":
        # 编辑用户
        kami_id = payload.get("kami_id")
        kami = db.query(Kami).filter(Kami.id == kami_id).first()
        if not kami:
            return JSONResponse({"success": False, "msg": "卡密不存在"})
        action = payload.get("action")
        print("action:::", action)
        if action == "get":
            auth_dicts = {
                "id": kami.id,
                "code": kami.code,
                "vip_type": kami.vip_type.value,
                "days": kami.days,
                "is_used": kami.is_used,
                "created_at": kami.created_at.strftime("%Y-%m-%d") if kami.created_at else None,
                "used_at": kami.used_at.strftime("%Y-%m-%d") if kami.used_at else None,
                "remark": kami.remark
            }

            return JSONResponse({
                "success": True,
                "kami": auth_dicts
            })
        else:
            if "is_used" in payload:
                kami.is_used = payload["is_used"]
            if "used_at" in payload:
                used_at_str = payload.get("used_at")
                if used_at_str:
                    try:
                        # 假设前端传入格式是 'YYYY-MM-DD'
                        kami.used_at = datetime.strptime(used_at_str, "%Y-%m-%d")
                    except ValueError:
                        kami.used_at = None
                else:
                    kami.used_at = None
            if "remark" in payload:
                kami.remark = payload["remark"]

            db.commit()
            return JSONResponse({"success": True, "msg": "更新成功"})

    elif action == "disable":
        # 禁用/启用用户
        kami_id = payload.get("kami_id")
        kami = db.query(Kami).filter(Kami.id == kami_id).first()
        if not kami:
            return JSONResponse({"success": False, "msg": "卡密不存在"})

        # 切换状态
        kami.is_used = 0 if kami.is_used == 1 else 1
        db.commit()
        return JSONResponse({"success": True, "msg": "用户状态更新成功"})

    else:
        return JSONResponse({"success": False, "msg": "未知操作"})


@router.get("/licenses")
def licenses(request: Request, page: int = Query(default=1, ge=1), page_size: int = Query(default=20, ge=1, le=50),
             search: str = "", db: Session = Depends(get_db), admin_user=Depends(admin_required)):
    # 基础查询
    query = db.query(Users)

    # 搜索
    if search:
        search_pattern = f"%{search}%"
        query = query.filter(
            or_(
                Users.username.ilike(search_pattern),
                Users.user_id.cast(String).ilike(search_pattern)
            )
        )

    # 总用户数
    total_users = query.count()

    # 分页计算
    offset = (page - 1) * page_size
    total_pages = (total_users + page_size - 1) // page_size  # 总页数（向上取整）

    # 分页
    users = query.order_by(Users.created_at.desc()).offset(offset).limit(page_size).all()

    # 今日日期
    today = datetime.now().date()

    # 遍历每个用户，绑定今日通话记录
    for user in users:
        # 查询当前用户的今日通话记录（使用 user.id 作为 user_id）
        today_call = (
            db.query(ApiCalls)
            .filter(
                ApiCalls.user_id == user.user_id,  # 关键：使用当前用户的 ID
                ApiCalls.call_date == today  # 匹配今日日期
            )
            .first()  # 获取第一条记录（或用 one()/all() 根据需求）
        )

        # 数据行 绑定到用户对象（添加属性 today_call）
        user.today_call = today_call  # 若没有记录则为 None

    # 渲染模板
    return templates.TemplateResponse("admin/admin_licenses.html", {
        "request": request,
        "admin_user": admin_user,
        "users": users,
        "total_users": total_users,
        "total_pages": total_pages,
        "page": page,
        "page_size": page_size,
        "search": search
    })


@router.get("/apilogs")
def apilogs(request: Request, page: int = Query(default=1, ge=1), page_size: int = Query(default=20, ge=1, le=50),
            search: str = "", db: Session = Depends(get_db), admin_user=Depends(admin_required)):
    # 基础查询：关联用户
    query = db.query(ApiCallLogs).join(Users)

    # 搜索用户名或用户ID
    if search:
        query = query.filter(
            (Users.username.ilike(f"%{search}%")) |
            (ApiCallLogs.url.ilike(f"%{search}%"))
        )

    # 总数
    total_apilogs = query.count()

    # 分页计算
    offset = (page - 1) * page_size
    total_pages = (total_apilogs + page_size - 1) // page_size  # 总页数（向上取整）

    # 数据
    data_apilogs = query.order_by(ApiCallLogs.created_at.desc()).offset(offset).limit(page_size).all()

    return templates.TemplateResponse("admin/admin_api_logs.html", {
        "request": request,
        "admin_user": admin_user,
        "data_apilogs": data_apilogs,
        "total_apilogs": total_apilogs,
        "total_pages": total_pages,
        "page": page,
        "page_size": page_size,
        "search": search
    })


# --------------------------
# 新增：辅助函数1 - 生成完整时间轴
# --------------------------
def generate_full_time_axis(time_range: str):
    """
    根据时间范围，生成连续无间断的时间轴（日期列表）：
    - week: 本周7天（周一到周日，即使今天是周三，也生成周一到周日的完整7天）
    - month: 本月所有日期（1号到当月最后一天，如9月1日到9月30日）
    - year: 本年12个月份的1号（1月1日、2月1日...12月1日，用于代表12个月份）
    """
    today = date.today()
    full_dates = []

    if time_range == "week":
        # 本周：周一到周日（固定7天，不管今天是周几）
        monday = today - timedelta(days=today.weekday())  # 本周一
        for i in range(7):
            full_dates.append(monday + timedelta(days=i))  # 周一到周日

    elif time_range == "month":
        # 生成本月所有日期的date对象
        first_day = today.replace(day=1)
        # 计算当月最后一天
        if today.month == 12:
            last_day = date(today.year + 1, 1, 1) - timedelta(days=1)
        else:
            last_day = date(today.year, today.month + 1, 1) - timedelta(days=1)
        # 遍历生成date对象
        current_day = first_day
        while current_day <= last_day:
            full_dates.append(current_day)  # date对象
            current_day += timedelta(days=1)

    elif time_range == "year":
        # 本年：12个月份的1号
        for month in range(1, 13):
            full_dates.append(date(today.year, month, 1))
            # full_dates.append(today.replace(month=month, day=1))

    return full_dates


# --------------------------
# 新增：辅助函数2 - 数据补0（合并实际数据与完整时间轴）
# --------------------------
def fill_empty_data(full_time_axis: List[date], actual_data: List[Tuple[date, int]], time_range: str):
    """
    将数据库查询到的实际数据，填充到完整时间轴中，无数据的时间点补0：
    :param full_time_axis: 完整时间轴（辅助函数1生成）
    :param actual_data: 数据库查询的实际数据（格式：[(date1, count1), (date2, count2), ...]）
    :return: 补0后的完整数据（格式：[{"date": "2024-09-01", "count": 123}, ...]）
    """
    # 1. 将实际数据转为字典（key：date对象，value：调用次数），方便快速匹配
    actual_data_dict = {item[0]: item[1] for item in actual_data}

    # 2. 遍历完整时间轴，填充数据（无数据补0）
    filled_data = []
    for date_obj in full_time_axis:
        # 时间范围为“year”时，日期格式显示为“2024-01”（月份），其他显示为“2024-09-01”（完整日期）
        # if len(full_time_axis) == 12:  # 本年12个月的情况
        #     date_str = date_obj.strftime("%Y-%m")  # 格式：YYYY-MM
        # else:
        #     date_str = date_obj.strftime("%Y-%m-%d")  # 格式：YYYY-MM-DD
        if time_range == "year":
            # 本年：显示为“01月 ~ 12月”
            date_str = date_obj.strftime("%m月")
        elif time_range == "month":
            # 本月：显示为“09-01 ~ 09-30”
            date_str = date_obj.strftime("%m-%d")
        else:  # week
            # 本周：默认显示“09-01”这种格式，也可以改成星期
            date_str = date_obj.strftime("%Y-%m-%d")

        filled_data.append({
            "date": date_str,
            "count": actual_data_dict.get(date_obj, 0)  # 有数据取实际值，无数据补0
        })

    return filled_data


# --------------------------
# 原有辅助函数：获取时间范围（无需修改）
# --------------------------
def get_date_range(time_range: str):
    today = date.today()
    if time_range == "month":
        return today.replace(day=1), today
    elif time_range == "year":
        return today.replace(month=1, day=1), today
    else:  # week
        return today - timedelta(days=today.weekday()), today


@router.get("/apicalls")
def apilogs(request: Request, page: int = Query(default=1, ge=1), page_size: int = Query(default=10, ge=1, le=50),
            search: str = "", time_range: str = Query("week", pattern="^(week|month|year)$"),
            db: Session = Depends(get_db), admin_user=Depends(admin_required)
            ):
    # 1. 获取时间范围 + 生成完整时间轴
    start_date, end_date = get_date_range(time_range)
    full_time_axis = generate_full_time_axis(time_range)  # 关键：生成无间断时间轴

    # 2. 基础查询（分页+搜索）：原有逻辑不变
    base_query = db.query(ApiCalls).join(
        Users, ApiCalls.user_id == Users.user_id
    ).filter(
        ApiCalls.call_date.between(start_date, end_date)
    )
    if search.strip():
        base_query = base_query.filter(Users.username.ilike(f"%{search.strip()}%"))
    total_apicalls = base_query.count()
    offset = (page - 1) * page_size
    data_apicalls = base_query.order_by(ApiCalls.id.desc()).offset(offset).limit(page_size).all()

    # -------------------------------------------------------------------------
    # 3. 调用统计（核心优化：用辅助函数生成完整数据，无数据补0）
    # -------------------------------------------------------------------------
    if time_range == "year":
        # SQLite：用strftime('%Y-%m-01', call_date)将日期转为“当月1号”的字符串
        # 再用DATE()函数转为Date类型，与时间轴的date对象匹配
        actual_daily_data = db.query(
            func.DATE(func.strftime('%Y-%m-01', ApiCalls.call_date)).label("month_date"),
            func.sum(ApiCalls.call_count).label("total_count")
        ).filter(
            ApiCalls.call_date.between(start_date, end_date)
        ).group_by(
            func.DATE(func.strftime('%Y-%m-01', ApiCalls.call_date))  # 按“当月1号”分组
        ).all()

    else:
        # 本周/本月：仍按日分组（不变）
        actual_daily_data = db.query(
            ApiCalls.call_date,
            func.sum(ApiCalls.call_count).label("total_count")
        ).filter(
            ApiCalls.call_date.between(start_date, end_date)
        ).group_by(
            ApiCalls.call_date
        ).all()

    # -------------------------------------------------------------------------
    # 4. 关键修复：格式转换时按时间维度区分字段名
    # 3.2 格式转换：将SQLAlchemy结果转为（date对象, 整数）的元组列表
    # -------------------------------------------------------------------------
    actual_data_tuple = []
    for item in actual_daily_data:
        if time_range == "year":
            date_obj = item.month_date  # 这应该已经是date对象
        else:
            date_obj = item.call_date  # 这应该已经是date对象

        # 安全检查：如果是字符串，转换为date对象
        if isinstance(date_obj, str):
            from datetime import datetime
            date_obj = datetime.strptime(date_obj, '%Y-%m-%d').date()

        actual_data_tuple.append((date_obj, int(item.total_count)))

    # 3.3 关键：数据补0（合并完整时间轴与实际数据）
    daily_chart_data = fill_empty_data(full_time_axis, actual_data_tuple, time_range)

    # 4. 用户调用排行TOP10：原有逻辑不变
    user_rank_stats = db.query(
        Users.username,
        func.sum(ApiCalls.call_count).label("total_calls")
    ).join(
        ApiCalls, Users.user_id == ApiCalls.user_id
    ).filter(
        ApiCalls.call_date.between(start_date, end_date)
    ).group_by(
        Users.username
    ).order_by(
        func.sum(ApiCalls.call_count).desc()
    ).limit(10).all()
    user_rank_data = [
        {"username": item.username, "total": int(item.total_calls)}
        for item in user_rank_stats
    ]

    # 5. 分页逻辑：原有逻辑不变
    total_pages = (total_apicalls + page_size - 1) // page_size if total_apicalls else 1
    current_page = max(1, min(page, total_pages))
    start_page = max(1, current_page - 2)
    end_page = min(total_pages, current_page + 2)

    # 6. 返回数据到模板
    return templates.TemplateResponse(
        "admin/admin_api_calls.html",
        {
            "request": request,
            "admin_user": admin_user,
            "data_apicalls": data_apicalls,
            "total_apicalls": total_apicalls,
            "page": current_page,
            "page_size": page_size,
            "search": search,
            "time_range": time_range,
            "daily_data": daily_chart_data,  # 传递补0后的完整数据
            "user_rank_data": user_rank_data,
            "total_pages": total_pages,
            "start_page": start_page,
            "end_page": end_page
        }
    )


# 用户每日调用详情接口
@router.get("/apicalls/user_daily")
def user_daily_calls(apicalls_id: int = Query(..., description="用户ID"),
                     db: Session = Depends(get_db),
                     request: Request = None):
    # 验证管理员权限
    if request:
        admin_required(request)

    # --------------------------
    # 第一步：通过 ID 查 user_id 和 call_date
    # --------------------------
    base_info = db.query(ApiCalls.user_id, ApiCalls.call_date).filter(ApiCalls.id == apicalls_id).first()
    print("base_info::::", base_info)

    # 提取参数（若 call_date 是 datetime，转成 date 类型，避免时分秒影响筛选）
    user_id = base_info.user_id
    # 处理 datetime → date（如果你的 call_date 是 date 类型，可直接写 current_call_date = base_info.call_date）
    current_call_date = base_info.call_date.date() if hasattr(base_info.call_date, 'date') else base_info.call_date

    # --------------------------
    # 第二步：查历史数据（当前 call_date 之前的7条）
    # --------------------------
    # 查询该用户的所有每日调用记录（按日期分组）
    user_daily_data = (db.query(ApiCalls.call_date,
                                func.sum(ApiCalls.call_count).label("total_calls"))
                       .filter(ApiCalls.user_id == user_id,
                               func.date(ApiCalls.call_date) < current_call_date)
                       .group_by(ApiCalls.call_date)
                       .order_by(ApiCalls.call_date.desc())
                       .limit(7)
                       .all())

    # # 查询该用户的所有每日调用记录（之前 ApiCalls.user_id == user_id）
    # user_daily_data = (db.query(ApiCalls.call_date,
    #                            func.sum(ApiCalls.call_count).label("total_calls"))
    #                    .filter(ApiCalls.user_id == user_id)
    #                    .group_by(ApiCalls.call_date)
    #                    .order_by(ApiCalls.call_date.desc())
    #                    .limit(7)
    #                    .all())

    # 转换为前端需要的格式
    formatted_data = [
        {
            "date": item.call_date.strftime("%Y-%m-%d"),
            "calls": item.total_calls
        }
        for item in user_daily_data
    ]

    # 获取用户名（用于展示）
    username = db.query(Users.username).filter(Users.user_id == user_id).scalar() or "未知用户"

    return JSONResponse({
        "success": True,
        "data": {
            "user_id": user_id,
            "username": username,
            "daily_records": formatted_data,
            "total_days": len(formatted_data),
            "total_calls": sum(item["calls"] for item in formatted_data)
        }
    })


# 1. 系统设置页面 - 渲染配置列表
@router.get("/system_config")
def system_config_page(request: Request,
                       status: Optional[int] = None,
                       db: Session = Depends(get_db), admin_user=Depends(admin_required)):
    # # 按 typeid 分组查询配置，保证前端模块展示顺序
    # configs = db.query(Config).order_by(Config.typeid, Config.orders).all()

    # 基础查询
    query = db.query(Config).order_by(Config.typeid, Config.orders)

    print(status)

    # 如果传了 status 参数，就筛选
    if status is not None:
        query = query.filter(Config.status == status)

    configs = query.all()

    # 整理配置为分组字典（key=typeid，value=该分组下的配置列表）
    config_groups: Dict[int, list] = {1: [], 2: [], 3: [], 4: []}
    for cfg in configs:
        config_groups[cfg.typeid].append(cfg)

    # 渲染页面，传递分组配置和分组名称映射
    return templates.TemplateResponse("admin/admin_system_config.html", {
        "request": request,
        "admin_user": admin_user,
        "config_groups": config_groups,
        "group_titles": {
            1: "系统基础设置",
            2: "调用次数限制",
            3: "会员价格设置",
            4: "支付方式设置"
        },
        "current_status": status
    })
    # return templates.TemplateResponse("admin/admin_system_config.html", {
    #     "request": request,
    #     "admin_user": admin_user,
    #     "config_groups": config_groups,
    #     "group_titles": {
    #         1: "系统基础设置",
    #         2: "调用次数限制",
    #         3: "会员价格设置",
    #         4: "支付方式设置"
    #     }
    # })


# 2. 配置更新接口 - 处理前端AJAX请求
@router.post("/system_config/update")
def update_config(field: str = Form(...), data: str = Form(...), db: Session = Depends(get_db),
                  admin_user=Depends(admin_required)):
    # 1. 查找对应的配置项
    config = db.query(Config).filter(Config.field == field).first()
    if not config:
        return JSONResponse(
            {"success": False, "msg": f"配置项「{field}」不存在"},
            status_code=404
        )

    # 2. 按配置类型做合法性校验（避免非法值）
    if field in ["config_free_api", "config_month_api", "config_season_api", "config_year_api"]:
        # 调用次数：必须是非负整数
        if not data.isdigit() or int(data) < 0:
            return JSONResponse(
                {"success": False, "msg": "调用次数必须是非负整数（如 100、5000）"},
                status_code=400
            )
    elif field in ["config_month_price", "config_season_price", "config_year_price"]:
        # 会员价格：必须是非负数字（支持小数）
        try:
            price = float(data)
            if price < 0:
                raise ValueError
        except ValueError:
            return JSONResponse(
                {"success": False, "msg": "价格必须是非负数字（如 19.99、49）"},
                status_code=400
            )
    elif field in ["config_wxpay", "config_alipay", "config_kamipay"]:
        # 支付开关：只能是 1（开启）或 0（关闭）
        if data not in ["0", "1"]:
            return JSONResponse(
                {"success": False, "msg": "支付开关只能选择「开启」或「关闭」"},
                status_code=400
            )

    # 3. 执行更新并提交
    config.data = data
    db.commit()
    db.refresh(config)

    # 4. 返回成功响应
    return JSONResponse({
        "success": True,
        "msg": "配置更新成功",
        "data": config.data  # 返回更新后的值，供前端校验
    })


# 编辑获取数据
@router.get("/system_config/{field}", summary="获取配置详情")
def get_config(field: str, db: Session = Depends(get_db), admin_user=Depends(admin_required)):
    config = db.query(Config).filter(Config.field == field).first()
    if not config:
        return {"success": False, "msg": "配置项不存在"}

    return {
        "success": True,
        "data": {
            "field": config.field,
            "title": config.title,
            "tip": config.tip,
            "typeid": config.typeid,
            "orders": config.orders,
            "data": config.data,
            "status": config.status
        }
    }


# 编辑更新保存配置
@router.post("/system_config/edit", summary="更新配置项")
def edit_config(field: str = Form(...), title: str = Form(...), tip: Optional[str] = Form(""),
                typeid: int = Form(...), orders: int = Form(...),
                status: int = Form(...), db: Session = Depends(get_db), _=Depends(admin_required)):
    config = db.query(Config).filter(Config.field == field).first()
    if not config:
        raise HTTPException(status_code=400, detail="配置项不存在")

    # 更新配置
    config.title = title
    config.tip = tip
    config.typeid = typeid
    config.orders = orders
    config.status = status

    db.commit()
    db.refresh(config)
    return {"success": True, "msg": f"配置项【{title}】更新成功"}


# 创建新配置
@router.post("/system_config/add")
def update_config(field: str = Form(...), title: str = Form(...),
                  tip: Optional[str] = Form("", description="提示信息"), typeid: int = Form(...),
                  orders: int = Form(...), db: Session = Depends(get_db), _=Depends(admin_required)):
    # 1. 校验字段唯一性
    if db.query(Config).filter(Config.field == field).first():
        raise HTTPException(status_code=400, detail=f"配置字段已存在: {field}")

    # 2. 校验字段名格式（只允许字母数字下划线）
    if not re.match(r'^[a-zA-Z0-9_]+$', field):
        raise HTTPException(status_code=400, detail="配置字段名仅允许字母、数字、下划线")

    # 3. 调整排序（插入时将同分组 >= orders 的记录 +1）
    if orders >= 0:
        db.query(Config).filter(
            Config.typeid == typeid,
            Config.orders >= orders
        ).update({Config.orders: Config.orders + 1})

    # 4. 新增到数据库
    try:
        new_config = Config(field=field, title=title, tip=tip, typeid=typeid, orders=orders)
        print(new_config)
        db.add(new_config)
        db.commit()
        db.refresh(new_config)

        return {"success": True, "msg": f"配置项【{title}】新增成功"}
    except Exception as e:
        db.rollback()
        raise HTTPException(status_code=500, detail=f"新增配置失败: {str(e)}")


@router.post("/system_config/status", summary="状态设置")
def edit_config(id: int = Form(...), db: Session = Depends(get_db),
                _=Depends(admin_required)):
    config = db.query(Config).filter(Config.id == id).first()
    if not config:
        raise HTTPException(status_code=400, detail="配置项不存在")

    # 更新配置
    config.status = 0 if config.status == 1 else 1
    status_str = "启用" if config.status == 1 else "禁用"

    db.commit()
    db.refresh(config)

    return {"success": True, "msg": f"配置项【{status_str}】成功", "status": status_str}
